package com.beantools.util;

import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Iterator;

import static com.beantools.util.ObjectUtil.isNotNull;
import static com.beantools.util.ObjectUtil.isNull;

/**
 * 这是容器的工具类，是泛型工具类。调用者可以根据泛型将容器转化为数组
 * 也可以，根据将数组转化为相应的容器
 *
 * @author baoya
 * @version 1.1.0
 * @since 1.0
 */
@SuppressWarnings("all")
public class CollectionUtil<E> implements Serializable {

    /**
     * 判断容器是否为空容器，如果容器为null，
     * 或者容器的长度为0，都是空容器
     *
     * @param coll 容器对象
     */
    public static boolean isEmpty(Collection coll) {
        return isNull(coll) || coll.size() == 0 ? true : false;
    }

    /**
     * 判断容器不是空容器，如果容器不为null，
     * 同时容器的长度不为0，才不是空容器
     *
     * @param coll 容器对象
     */
    public static boolean isNotEmpty(Collection coll) {

        return isNotNull(coll) && coll.size() >= 1 ? true : false;
    }

    /**
     * 这个方法用来判断容器是否包含空对象
     *
     * @param coll 包含空对象，返回true，否则，返回false
     */
    public static boolean containNullObj(Collection coll) {
        if (isEmpty(coll)) {
            return true;
        }
        for (Object o : coll) {
            if (isNull(o)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 这个方法用来判断容器没有空对象
     *
     * @param coll 没有空对象，返回true，否则，返回false
     */
    public static boolean notAnyNullObj(Collection coll) {
        if (isEmpty(coll)) {
            return false;
        }
        for (Object o : coll) {
            if (isNull(o)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 根据泛型容器中的类型，将泛型容器转化为对象数组,比如：
     * <pre>
     *       Set<Person> personSet = new HashSet<>();
     *       personSet.add(new Person("name1", "phone1"));
     *       personSet.add(new Person("name2", "phone3"));
     *       Person[] persons = CollectionUtil.toArray(Collection<E> coll)
     * </pre>
     *
     * @param coll  泛型容器
     * @param clazz 泛型对象
     * @return 泛型对象数组
     * @throws IllegalArgumentException 如果容器为空或者类字面常量为空，则会抛出异常
     */
    public static <E> E[] makeCollArray(Collection<E> coll, Class<? extends E> clazz) throws IllegalArgumentException {
        if (CollectionUtil.isEmpty(coll)) {
            throw new IllegalArgumentException("容器为空，转化毫无意义");
        }
        if (isNull(clazz)) {
            throw new IllegalArgumentException("类类字面不能为空");
        }
        E[] arrays = (E[]) Array.newInstance(clazz, coll.size());
        int index = 0;
        for (E E : coll) {
            arrays[index++] = E;
        }
        return arrays;
    }

    /**
     * 这是去除空对象的方法。如果容器包含空对象，那么就去除空对象，比如
     * <pre>
     *     <code>
     *          @Ignore
     *          public void testRemoveNullObject() {
     *              Goods goods1 = new Goods();
     *              goods1.setName("商品1");
     *              Goods goods2 = new Goods();
     *              goods2.setNo(SimpleDate.getInstance(ISO_DATETIME_FORMAT).format(new Date()));
     *              List<Goods> goodsList = new ArrayList<>();
     *              goodsList.add(goods1);
     *              goodsList.add(goods2);
     *              goodsList.add(null);
     *              goodsList.add(null);
     *              System.out.println(CollectionUtil.removeNullObject(goodsList).size());
     *          }
     *     </code>
     * </pre>
     *
     * @param coll 如果没有空对象，返回原来容器；如果存在空对象，则执行去除空对象的操作
     */
    public static Collection removeNullObject(Collection coll) {
        if (notAnyNullObj(coll)) {
            return coll;
        }
        Iterator iterator = coll.iterator();
        while (iterator.hasNext()) {
            Object obj = iterator.next();
            if (isNull(obj)) {
                iterator.remove();
            }
        }
        return coll;
    }


}
